from selenium import webdriver
import requests
import time
import datetime
import re
import pandas as pd
from bs4 import BeautifulSoup
import warnings
warnings.filterwarnings('ignore')

# 爬虫
class Scrapy:
    """
    :parameter

    flagDfcf : 是否开启东方财富爬虫
    flagKcbrb : 是否开启科创版日报爬虫
    windowCount ： 默认一个窗口为90s， 经历windowCount次后输出数据；
    biginningIndex ：科创版日报爬取网站的起始位置，可通过查看url自由选取；

    :arg

    outputCount ： 输出文件的后缀名
    flag : 开启webDriver的开关，默认True
    errorCount ： 爬虫出错的次数
    hashContent ： 文章标题的哈希值集合
    data ： 每次输出的内容
    """

    # 初始化
    def __init__(self, flagDfcf=False, flagKcbrb=False, windowCount=4, beginningIndex=766707):
        self.flagDfcf = flagDfcf
        self.flagKcbrb = flagKcbrb
        self.windowCount = windowCount
        self.windowCount_ = windowCount
        self.beginningIndex = beginningIndex
        self.outputCount = 0
        self.flag = True
        self.errorCount = 0
        self.hashDfcfContent = []
        self.hashKcbrbContent = []
        self.data = pd.DataFrame({"title": [""], "time": [""], "content": [""]})

    # 爬虫执行程序
    def run(self):
        self.clear()
        while (True):
            self.windowCount_ -= 1
            self.runDfcf()
            self.runKcbrb()
            # 每隔90秒启动一次
            time.sleep(5)
            # 进行数据输出
            if self.windowCount_ <= 0:
                self.data.to_csv("scrapy{}.csv".format(self.outputCount), index=False)
                self.outputCount += 1
                self.windowCount_ = self.windowCount
                self.data = pd.DataFrame({"title": [""], "time": [""], "content": [""]})
            print("----------------------------")
            print("DATA数据为" + self.data)

    # 清除缓存中的值
    def clear(self):
        self.data = pd.DataFrame({"title": [""], "time": [""], "content": [""]})
        self.hashKcbrbContent = []
        self.hashDfcfContent = []
        self.errorCount = 0

    # 东方财富爬虫执行
    def runDfcf(self):
        flag1 = self.flagDfcf
        while (flag1):
            self.scrapyDfcf()
            flag1 = False

    # 科创版日报爬虫执行
    def runKcbrb(self):
        flag2 = self.flagKcbrb
        while (flag2):
            self.scrapyKcbrb()
            flag2 = False

    # 东方财富爬虫主逻辑
    def scrapyDfcf(self):
        # 声明全局变量
        global DRIVER
        while (self.flag):
            DRIVER = webdriver.Chrome('D:\pythonProject\chromedriver.exe')
            html = DRIVER.get('https://kuaixun.eastmoney.com/')
            # 只运行一次web，因为这个网站会自动更新
            self.flag = False

        try:
            # 东方财富新闻爬虫主逻辑
            element = DRIVER.find_element_by_class_name("media-content")
            # 得到最新的爬取内容
            text = element.text

            # 获取标题
            pt1 = re.compile(r'【.*】')
            res1 = re.findall(pt1, str(text))
            kcbrbTitle = str(res1).replace("【", "").replace("】", "").replace("['", "").replace("']", "")

            # 获取时间
            element = DRIVER.find_element_by_class_name("time")
            kcbrbTime = element.text
            nowTime = datetime.datetime.now()
            nowTimeMonth = nowTime.month
            if ( len(str(nowTime.month)) == 1 ):
                nowTimeMonth = "0" + str(nowTime.month)
            kcbrbTime = str(nowTime.year) + "-" + nowTimeMonth + "-" + str(nowTime.day) + " " + kcbrbTime

            # 获取正文
            pt2 = re.compile(r'】.*')
            res2 = re.findall(pt2, str(text))
            kcbrbcontent = str(res2).replace("'】", "").replace("。（'", "").replace("[", "").replace("]", "").replace("'", "")

            # 数据处理
            data1 = pd.DataFrame(kcbrbTitle, columns=["title"], index=range(1))
            data2 = pd.DataFrame(kcbrbTime, columns=["time"], index=range(1))
            data3 = pd.DataFrame(kcbrbcontent, columns=["content"], index=range(1))
            data4 = pd.concat([data1, data2, data3], axis=1)

            # 判断文章是否已经获取过
            # 对每个文章标题做哈希计算，将值保存起来
            hashCode = hash(kcbrbTitle)

            # 保存好第一条数据
            if len(self.hashDfcfContent) == 0:
                self.hashDfcfContent.append(hashCode)
                self.data = data4
            # 针对后续数据做判断
            else:
                # 与前一条获取到的数据的哈希值做判断，若不同，说明这是一条新数据，加入集合中；
                if (hashCode != self.hashDfcfContent[-1]):
                    self.hashDfcfContent.append(hashCode)
                    self.data = pd.concat([self.data, data4])
                    self.data.index = range(len(self.data))

        # 爬虫出错后逻辑
        except:
            self.errorCount += 1
            print("失败{}次".format(self.errorCount))

    # 科创版日报爬虫主逻辑
    def scrapyKcbrb(self):
        # 科创板日版爬虫主逻辑
        # 计算url后缀增长次数
        count = 0
        # 统计每次成功爬取网页数据时所增长的次数
        step = 0
        # 表示成功抽取到网页数据
        flag = False
        # 每一轮测试20条数据，如果
        for i in range(1, 20):
            count += 1
            # 爬取文章主体内容
            r = requests.get("https://www.chinastarmarket.cn/detail/{}".format(self.beginningIndex + count)).content.decode("utf-8")
            bs1 = BeautifulSoup(r, "lxml")

            try:
                # 爬取正文
                pt1 = re.compile(r'detail-telegraph-content content">(.*?)</div>')
                res1 = re.findall(pt1, str(bs1))
                content = str(res1).replace("【", "").replace("】", "").replace("[", "").replace("]", "").replace("'", "")

                # 爬取标题
                pt2 = re.compile(r'<title class="next-head">(.*?)</title>')
                res2 = re.findall(pt2, str(bs1))
                title = str(res2).replace("[", "").replace("]", "").replace("'", "")

                # 爬取时间
                pt3 = re.compile(r'c-222">(.*?)</span></div>')
                res3 = re.findall(pt3, str(bs1))
                time = str(res3).replace("[", "").replace("]", "").replace("'", "").replace("年","-").replace("月","-")
                time = time[:-3]

                if res1 != []:
                    # 抽取到了数据
                    flag = True
                    # 更新爬取到数据时的后缀值增长次数
                    step = count
                    # 数据处理
                    hashCode = hash(str(content))
                    Data1 = pd.DataFrame(title, columns=["title"], index=range(1))
                    Data2 = pd.DataFrame(time, columns=["time"], index=range(1))
                    Data3 = pd.DataFrame(content, columns=["content"], index=range(1))
                    Data4 = pd.concat([Data1, Data2, Data3], axis=1)

                    if len(self.hashKcbrbContent) == 0:
                        self.hashKcbrbContent.append(hashCode)
                        self.data = pd.concat([self.data, Data4])
                        self.data.index = range(len(self.data))

                    else:
                        # 与前一条获取到的数据的哈希值做判断，若不同，说明这是一条新数据，加入集合中；
                        if (hashCode != self.hashKcbrbContent[-1]):
                            self.hashKcbrbContent.append(hashCode)
                            self.data = pd.concat([self.data, Data4])
                            self.data.index = range(len(self.data))


            except:
                self.errorCount += 1
                print("失败{}次".format(self.errorCount))
        if flag:
            self.beginningIndex += step